package edu.towson.cosc.cosc455.mlam4.compiler;
import edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer;

public class MySyntaxAnalyzer implements  SyntaxAnalyzer{

	@Override
	public void lolcode() {
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.DOC_BEGIN)) {
			System.err.println("SYNTAX ERROR: Incorrect Token"+ MyCompiler.token + "When "
					+ LexicalTokens.DOC_BEGIN + " Expected.");
			System.exit(0);
		}
		else{
			MyCompiler.parseTree.add(MyCompiler.token);
			MyCompiler.Lexer.getNextToken();
			if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_BEGIN))
				comment();
			else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.HEAD_BEGIN))
				head();
			else if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_DEFINE_BEGIN))
				define();
		}
		body();
		
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.DOC_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " when " + LexicalTokens.DOC_END + " was expected.");
			System.exit(0);
		}
		else{
            MyCompiler.parseTree.add(MyCompiler.token);
            if (!MyCompiler.Lexer.fileEnd()){
                    System.err.println("SYNTAX ERROR: Text Found After #KTHXBYE");
                    System.exit(0);
            }

		}
	}
		


	public void comment() {
		MyCompiler.parseTree.add(MyCompiler.token);
		MyCompiler.Lexer.getNextToken();
		
		if (!MyCompiler.token.startsWith("#")){
			text();
		}
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.COMMENT_END+ " is expected.");
			System.exit(0);
		}
		else{
			MyCompiler.parseTree.add(MyCompiler.token);
			MyCompiler.Lexer.getNextToken();
		}
	}
	
	
	public void text(){
		MyCompiler.parseTree.add(MyCompiler.token);
		
		MyCompiler.Lexer.getNextToken();
	}
	
	
	
	public void head() {
		MyCompiler.parseTree.add(MyCompiler.token);
		MyCompiler.Lexer.getNextToken();
		
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.TITLE_BEGIN)){
			title();
		}
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.HEAD_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.HEAD_END+ " is expected.");
			System.exit(0);
		}
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();

	}
	
	
	public void title() {
		MyCompiler.parseTree.add(MyCompiler.token);
		MyCompiler.Lexer.getNextToken();

		if(!MyCompiler.token.startsWith("#")){
			text();
		}

		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.TITLE_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.TITLE_END+ " is expected.");
			System.exit(0);
		}		
		MyCompiler.parseTree.add(MyCompiler.token);
		MyCompiler.Lexer.getNextToken();

	}
	
	
	
	public void paragraph() {
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();
        if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_DEFINE_BEGIN))
        	define();
        innerParagraph();

		
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.PARAGRAPH_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.PARAGRAPH_END+ " is expected.");
			System.exit(0);
		}
		
		MyCompiler.parseTree.add(MyCompiler.token);
		MyCompiler.Lexer.getNextToken();
		
	}

	
	
	public void bold() {
		// TODO Auto-generated method stub
		
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();

        if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_DEFINE_BEGIN))
        	define();
        innerText();

		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.BOLD_END+ " is expected.");
			System.exit(0);
		}
		MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();


	}

	
	
	public void italics() {
		// TODO Auto-generated method stub
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();
        if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_DEFINE_BEGIN))
        	define();
        innerText();
		
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.ITALICS_END+ " is expected.");
			System.exit(0);
		}
		MyCompiler.parseTree.add(MyCompiler.token);
		MyCompiler.Lexer.getNextToken();

	}

	
	
	public void list() {
		// TODO Auto-generated method stub
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();
        
        if (!MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN)){
        	System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.ITEM_BEGIN + " is expected.");
        	System.exit(0);
        }
        else
        	item();
        
        
        if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_END)){
        	System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.LIST_END+ " is expected.");
        	System.exit(0);
        }		
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();

	}

	
	
	
	public void item() {
		// TODO Auto-generated method stub
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();
        innerList();
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.ITEM_END+ " is expected.");
			System.exit(0);
		}		
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();
        
        if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN))
        item();
        }

	
	public void newLine(){
		MyCompiler.parseTree.add(MyCompiler.token);
		MyCompiler.Lexer.getNextToken(); 
	}
	
	
	
	public void audio() {
		// TODO Auto-generated method stub
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();
        if (!MyCompiler.token.startsWith("#")){
            text();
        }
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.SOUNDS_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.SOUNDS_END+ " is expected.");
			System.exit(0);
		}
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();
	}

	
	public void video() {
		// TODO Auto-generated method stub
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();

        if (!MyCompiler.token.startsWith("#")){
            text();
        }
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.VIDEO_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.VIDEO_END+ " is expected.");
			System.exit(0);
		}		
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();
	}
	
	@Override
	public void define() {
		// TODO Auto-generated method stub
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();

		
		
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_DEFINE_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.VARIABLE_DEFINE_END+ " is expected.");
			System.exit(0);
		}		
	}

	
	
	
	public void use() {
		// TODO Auto-generated method stub
        MyCompiler.parseTree.add(MyCompiler.token);
        MyCompiler.Lexer.getNextToken();
        if (!MyCompiler.token.startsWith("#")){
            text();
        }
		
		if(!MyCompiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_USE_END)){
			System.err.println("SYNTAX ERROR: " + MyCompiler.token + " found when " + LexicalTokens.VARIABLE_USE_END+ " is expected.");
			System.exit(0);
		}
		MyCompiler.parseTree.add(MyCompiler.token);
		MyCompiler.Lexer.getNextToken();
	}
	

	public void body(){
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_BEGIN)){
			comment();
			body();       
		}
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.PARAGRAPH_BEGIN)){
			paragraph();
			body();
		}
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
            bold();
            body();
		}
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_BEGIN)){
			italics();
			body();
		}
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
			list();
			body();
		}
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.NEWLINE)){
			newLine();
			body();
		}
	}
	
	
	
	public void innerParagraph(){
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
            bold();
            innerParagraph();
		}
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_BEGIN)){
			italics();
			innerParagraph();
		}
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
			list();
			innerParagraph();
		}
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN)){
			item();
			innerParagraph();
		}		
	}
	
	public void innerText(){
		if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.SOUNDS_BEGIN)){
			audio();
			innerText();
		}
		else if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.VIDEO_BEGIN)){
			video();
			innerText();
		}
		else if (!MyCompiler.token.startsWith("#")){
			text();
			innerText();
		}
		else if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.NEWLINE)){
			newLine();
			innerText();
		}
		else if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_USE_BEGIN)){
			use();
            innerText();
		}
	}
	public void innerList(){
		if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
			bold();
			innerList();
		}
		else if (MyCompiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_BEGIN)){
			italics();
			innerList();
		}
		else if(MyCompiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN))
			list();
		
		innerText();
		
	}
	
}
	

